package cn.jwtool.jwcache.buffer.data;

import cn.jwtool.jwcache.buffer.config.JwcatchConfig;
import cn.jwtool.jwcache.buffer.data.backup.RdbModel;
import cn.jwtool.jwcache.buffer.data.backup.Serialization;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author : willian fu
 * @version : 1.0
 * 数据持久化恢复加载
 */
public class Recover {

    public static FileInputStream loadBackUpFile(boolean type) {
        try {
            return new FileInputStream(JwcatchConfig.getLogPath() + "\\RDB.rdb");
        } catch (FileNotFoundException e) {}
        return null;
    }

    public static void runRdbRecover() {
        FileInputStream inputStream = loadBackUpFile(true);
        if (null == inputStream) {
            return;
        }
        try {
            byte[] header = new byte[4];
            inputStream.read(header);
            if (verifyHeader(header)) {
                byte[] len = new byte[4];
                inputStream.read(len);
                int length = bytesToInt(len);
                if (length > 0) {
                    byte[] data = new byte[length];
                    inputStream.read(data);
                    RdbModel rdbModel = Serialization.DEFAULT.deserialization(data, RdbModel.class);
                    Catch.data.putAll(rdbModel.getData());
                    Catch.expired.putAll(rdbModel.getExpired());
                }
            } else {
                throw new RuntimeException("RDB持久化备份文件格式错误，跳过加载");
            }
        } catch (IOException e) {

        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    private static boolean verifyHeader(byte[] header) {
        if (header.length != 4) {
            return false;
        } else if (header[0] == (byte) 0xCA && header[1] == (byte) 0xFE
                && header[2] == (byte) 0xBA && header[3] == (byte) 0xDB) {
            return true;
        } else {
            return false;
        }
    }

    private static int bytesToInt(byte[] bytes) {
        int b0 = bytes[0] & 0xFF;
        int b1 = bytes[1] & 0xFF;
        int b2 = bytes[2] & 0xFF;
        int b3 = bytes[3] & 0xFF;
        return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
    }

}
